
#include <QXmlStreamReader>
#include <QFile>
#include <QDebug>

#include "LanguageXmlSerializer.h"
#include "LanguageModel.h"

LanguageXmlSerializer::LanguageXmlSerializer()
{

}

LanguageXmlSerializer::~LanguageXmlSerializer()
{

}

bool LanguageXmlSerializer::saveFile( const QString & filename, const LanguageModel * model )
{
    QFile
        file( filename );
        
    if( !file.open( QIODevice::WriteOnly | QIODevice::Text ) )
    {
        return false;
    }
    
    streamWriter = new QXmlStreamWriter( &file );
    streamWriter->setAutoFormatting( true );
    
    streamWriter->writeStartDocument();
    streamWriter->writeStartElement( "Localizations" );
    
	foreach( const LanguageElement & language_element, model->getLanguageElementTable() )
    {
        streamWriter->writeStartElement( "Localization" );
        streamWriter->writeAttribute( "Index" , QString::number( language_element.index ) );
		streamWriter->writeAttribute( "Status" , QString::number( language_element.status ) );
		streamWriter->writeTextElement( "Text", language_element.text );
        
        streamWriter->writeEndElement();
    }
    
    streamWriter->writeEndElement();
    streamWriter->writeEndDocument();
    delete streamWriter;

    return true;
}

bool LanguageXmlSerializer::loadFile( const QString & filename, LanguageModel * model )
{
    QFile
        file( filename );
        
    if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
    {
        return false;
    }
    
    streamReader = new QXmlStreamReader( &file );
    
    while (!streamReader->atEnd() )
    {
        switch( streamReader->readNext() )
        {
            case QXmlStreamReader::StartDocument:
                break;
            
            case QXmlStreamReader::StartElement:
            {
                if( streamReader->name() == "Localizations" )
                {
                    handleLanguage();
                }
                else
                {
                    //TODO throw exception
                }

            }
            break;
                
            case QXmlStreamReader::Characters:
            {
                Q_ASSERT( streamReader->isWhitespace() );
            }
            break;
                
            case QXmlStreamReader::EndDocument:
                break;

            default:
                qDebug() << "Unexpected element " << streamReader->tokenString() << "\n";
                delete streamReader;
                return false;
        }
    }
    
    if ( streamReader->hasError() ) 
    {
        qDebug() << "Error in xml : " << streamReader->errorString();
        delete streamReader;
        return false;
    }

    model->initializeModel( LanguageTable );
    

    delete streamReader;
    return true;
}

void LanguageXmlSerializer::handleLanguage()
{
    QXmlStreamReader::TokenType tokenType = streamReader->readNext();
    
    while ( tokenType != QXmlStreamReader::EndElement )
    {
        switch( tokenType )
        {
            case QXmlStreamReader::StartElement:
            {
                if( streamReader->name() == "Localization" )
                {
                    handleLanguageElement();
                }
                else
                {
                    qDebug() << "Unsupported tag " << streamReader->name() << " in Label tag\n";
                }

                break;
            }
            
            case QXmlStreamReader::Characters:
            {
                Q_ASSERT( streamReader->isWhitespace() );
            }
            break;

            default:
                qDebug() << "Unexpected element " << streamReader->tokenType() << "\n";
                return;
        }
        
        tokenType = streamReader->readNext();
    }
}

void LanguageXmlSerializer::handleLanguageElement()
{
    QXmlStreamAttributes 
        attributes = streamReader->attributes();
    QString
        index_string;
    bool
        index_is_integer;
    int
        index;
    QXmlStreamReader::TokenType
        tokenType;
    LanguageElement
        language_element;
        
    if( attributes.hasAttribute( "Index" ) )
    {

        index_string = attributes.value( "Index" ).toString();
        index = index_string.toInt( &index_is_integer );
        
        if( !index_is_integer )
        {
            //:TODO:
            qDebug() << "index is not an integer but is \"" << index_string << "\"";
            return;
        }
    }
    
    language_element.index = index;
    
    tokenType = streamReader->readNext();
    
    while ( tokenType != QXmlStreamReader::EndElement )
    {
        switch( tokenType )
        {
            case QXmlStreamReader::StartElement:
            {
                if( streamReader->name() == "Status" )
                {
					QString status_text;
					status_text = readLeafNode();
					language_element.status = status_text.toInt();
                }
                else if( streamReader->name() == "Text" )
                {
					language_element.text = readLeafNode();
                }
                else
                {
                    qDebug() << "unsupported tags " << streamReader->name() << " in element Localization";
                }

                break;
            }
            
            case QXmlStreamReader::Characters:
            {
                Q_ASSERT( streamReader->isWhitespace() );
            }
            break;

            default:
                qDebug() << "Unexpected element " << streamReader->tokenType() << "\n";
                return;
        }
        
        tokenType = streamReader->readNext();
    }
    
	LanguageTable.push_back( language_element );
    
}

QString LanguageXmlSerializer::readLeafNode()
{
    QString
        result;
    QXmlStreamReader::TokenType
        tokenType;
        
    tokenType = streamReader->readNext();
    
    while ( tokenType != QXmlStreamReader::EndElement )
    {
        if( tokenType == QXmlStreamReader::Characters )
        {
            result += streamReader->text();
        }
        else
        {
            qDebug() << "Unexpected element " << streamReader->tokenType() << "\n";
            return "";
        }

        
        tokenType = streamReader->readNext();
    }
    
    return result;
}